package cn.net.shuxing.yifu.common.service;

import cn.net.shuxing.yifu.common.bean.*;
import cn.net.shuxing.yifu.common.constant.CashChangeType;
import cn.net.shuxing.yifu.common.constant.Type;
import cn.net.shuxing.yifu.common.constant.UserState;
import cn.net.shuxing.yifu.common.constant.UserType;
import cn.net.shuxing.yifu.common.dto.BaseDto;
import cn.net.shuxing.yifu.common.dto.TransferHistoryDto;
import cn.net.shuxing.yifu.common.util.CommonExample;
import cn.net.shuxing.yifu.common.util.LocalDateTimeUtil;
import cn.net.shuxing.yifu.common.util.RedisKeyCreator;
import cn.net.shuxing.yifu.common.util.TimeExample;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import cn.net.shuxing.yifu.common.util.StringUtils;
import redis.clients.jedis.Jedis;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

public class ShareholderCommonService extends UserCommonService {

    @Autowired
    protected CoinTypeService coinTypeService;

    @Autowired
    protected ShareholderService shareholderService;

    @Autowired
    protected CardTypeService cardTypeService;

    @Autowired
    protected UserInfoBindService userInfoBindService;

    @Autowired
    protected CashWalletService cashWalletService;

    @Autowired
    protected AliveCoinActivateHistoryService aliveCoinActivateHistoryService;

    @Autowired
    protected ShareholderBonusService shareholderBonusService;

    @Autowired
    protected ShareholderLevelService shareholderLevelService;

    @Autowired
    protected ShareholderCoinGrantHistoryService shareholderCoinGrantHistoryService;

    @Autowired
    protected ShareholderShouldPayService shareholderShouldPayService;

    @Autowired
    protected LevelGrantService levelGrantService;

    @Autowired
    protected ShareholderWalletService shareholderWalletService;

    @Autowired
    protected ShareholderBonusListService shareholderBonusListService;

    @Override
    public List<UserCompletedInfo> searchByRealName(String name) {
        List<UserRealInfo> userRealInfos = userRealInfoService.getsByRealName(name);
        List<UserCompletedInfo> userCompletedInfoList = new ArrayList<>(userRealInfos.size());
        if (userCompletedInfoList == null || userCompletedInfoList.isEmpty()) {
        } else {
            for (UserRealInfo userRealInfo : userRealInfos) {
                userCompletedInfoList.add(getByUserId(userRealInfo.getId()));
            }
        }
        return userCompletedInfoList;
    }


    @Override
    public ShareholderCompletedInfo searchByPhoneNum(String phoneNum) {
        UserCompletedInfo info = super.searchByPhoneNum(phoneNum);
        ShareholderCompletedInfo shareholderCompletedInfo = new ShareholderCompletedInfo();
        if (info == null) {
        } else {
            User user = info.getUser();
            if (user == null) {
            } else {
                Integer id = user.getId();
                shareholderCompletedInfo = getByUserId(id);
            }
        }
        return shareholderCompletedInfo;
    }

    @Override
    public ShareholderCompletedInfo searchByIdCardNum(String idCardNum) {
        UserCompletedInfo info = super.searchByIdCardNum(idCardNum);
        User user = info.getUser();
        Integer id = 0;
        if (user == null) {
        } else {
            id = user.getId();
        }
        if (id != null) {
        } else {
            return getByUserId(id);
        }
        return null;
    }

    @Override
    public List<UserCompletedInfo> searchByRegistDate(LocalDateTime lowDate, LocalDateTime highDate) {
        List<UserCompletedInfo> userCompletedInfos = super.searchByRegistDate(lowDate, highDate);
        List<UserCompletedInfo> userCompletedInfoList = new ArrayList<>(userCompletedInfos.size());
        for (UserCompletedInfo info : userCompletedInfos) {
            userCompletedInfoList.add(getByUserId(info.getUser().getId()));
        }
        return userCompletedInfoList;
    }

    @Override
    public List<UserCompletedInfo> searchByRegistDate(LocalDate date) {
        List<UserCompletedInfo> userCompletedInfos = super.searchByRegistDate(date);
        List<UserCompletedInfo> userCompletedInfoList = new ArrayList<>(userCompletedInfos.size());
        for (UserCompletedInfo info : userCompletedInfos) {
            userCompletedInfoList.add(getByUserId(info.getUser().getId()));
        }
        return userCompletedInfoList;
    }

    @Override
    public List<UserCompletedInfo> searchBySleepCoinCount(Integer coinTypeId, BigDecimal low, BigDecimal high) {
        List<UserCompletedInfo> userCompletedInfos = super.searchBySleepCoinCount(coinTypeId, low, high);
        List<UserCompletedInfo> userCompletedInfoList = new ArrayList<>(userCompletedInfos.size());
        for (UserCompletedInfo info : userCompletedInfos) {
            userCompletedInfoList.add(getByUserId(info.getUser().getId()));
        }
        return userCompletedInfoList;
    }

    @Override
    public List<UserCompletedInfo> searchByAliveCoinCount(Integer coinTypeId, BigDecimal low, BigDecimal high) {
        List<UserCompletedInfo> userCompletedInfos = super.searchByAliveCoinCount(coinTypeId, low, high);
        List<UserCompletedInfo> userCompletedInfoList = new ArrayList<>(userCompletedInfos.size());
        for (UserCompletedInfo info : userCompletedInfos) {
            userCompletedInfoList.add(getByUserId(info.getUser().getId()));
        }
        return userCompletedInfoList;
    }

    @Override
    public List<UserCompletedInfo> searchByState(Integer state) {
        List<UserCompletedInfo> userCompletedInfos = super.searchByState(state);
        List<UserCompletedInfo> userCompletedInfoList = new ArrayList<>(userCompletedInfos.size());
        for (UserCompletedInfo info : userCompletedInfos) {
            userCompletedInfoList.add(getByUserId(info.getUser().getId()));
        }
        return userCompletedInfoList;
    }

    public boolean grantCoin(Integer shareholderId, Integer coinTypeId, BigDecimal count, int type) {
        UserCapital userCapital = userCapitalService.getByUserIdAndCoinTypeId(shareholderId, coinTypeId);
        if (userCapital == null) {
            return false;
        }

        /** 插入到数据库中 **/
        userCapitalService.update(userCapital);

        //Jedis //jedis = jedisUtil.getJedis();
        String s = jedisUtil.get(RedisKeyCreator.openPrice(coinTypeId));
        //jedisUtil.close();
        BigDecimal oldPrice = new BigDecimal(0);
        if (StringUtils.hasText(s))
            oldPrice = new BigDecimal(s);

        /** 开始插入货币配发记录 **/
        shareholderCoinGrantHistoryService.insert(coinTypeId, shareholderId, count, type, oldPrice, userDealHistoryService.createOrderNo(8));

        return true;
    }

    // TODO: 2019-06-02 空指针
    public void grantCoin(Integer shareholderId, int coinTypeId) {
        if (!checkShareholderState(shareholderId))
            return;
        //at cn.net.shuxing.yifu.common.service.ShareholderCommonService.grantCoin(ShareholderCommonService.java:191) ~[classes/:na]
        ShareholderLevel shareholderLevel = shareholderLevelService.getByShareholderId(shareholderId);
        LevelGrant levelGrant = levelGrantService.getsByLevelAndCoinTypeId(shareholderLevel.getLevel(), coinTypeId);
        grantCoin(shareholderId, coinTypeId, levelGrant.getAliveCoinCount(), Type.ALIVECOIN);
    }


    public void grantCoin(int coinTypeId) {
        List<Integer> ids = userRoleService.getsByUserRole(UserType.SHAREHOLDER);
        ids.forEach((x) -> {
            grantCoin(x, coinTypeId);
        });
    }

    /**
     * 给股东发放分红
     *
     * @param shareholderId 股东Id
     * @param totalAccount  当月分红总金额
     * @return
     */

    public BigDecimal giveShareholderBonus(Integer shareholderId, BigDecimal totalAccount, Integer coinTypeId, String uuid) {

        UserCapital userCapital = userCapitalService.getByUserIdAndCoinTypeId(shareholderId, coinTypeId);

        /** 股东持有休眠币数量 **/
        BigDecimal shareholderKeepSleepCoinCount = userCapital.getSleepCoinCount();

        /** 平台发放休眠币总量 **/
        BigDecimal platformGrantTotalSleepCoinCount = new BigDecimal(0);
        List<ShareholderCoinGrantHistory> shareholderCoinGrantHistoryList = shareholderCoinGrantHistoryService.getsByCoinTypeIdAndType(coinTypeId, Type.SLEEPCOIN);
        for (ShareholderCoinGrantHistory shareholderCoinGrantHistory : shareholderCoinGrantHistoryList) {
            platformGrantTotalSleepCoinCount = platformGrantTotalSleepCoinCount.add(shareholderCoinGrantHistory.getCount());
        }

        BigDecimal bonusRate = shareholderKeepSleepCoinCount.divide(platformGrantTotalSleepCoinCount, 8, BigDecimal.ROUND_HALF_UP);
        ShareholderBonus shareholderBonus = new ShareholderBonus();
        BigDecimal bonusCount = totalAccount.multiply(bonusRate);
        if (checkShareholderState(shareholderId)) {
            shareholderBonus.setBonus(bonusCount);
            shareholderBonus.setBonusUnpay(new BigDecimal(0));
            cashWalletService.addCash(shareholderId, bonusCount, CashChangeType.CASH_SHAREHOLDER_BONES, uuid);
        } else {
            shareholderBonus.setBonus(new BigDecimal(0));
            shareholderBonus.setBonusUnpay(bonusCount);
        }

        shareholderBonus.setBonusKey(uuid);
        shareholderBonus.setShareholderId(shareholderId);
        shareholderBonusService.insert(shareholderBonus);
        return shareholderBonus.getBonus();
    }

    public BaseDto giveShareholderBonus(BigDecimal totalAccount, Integer coinTypeId) {
        BaseDto baseDto = new BaseDto();
        String orderNo = userDealHistoryService.createOrderNo(8);
        StringBuilder builder = new StringBuilder();
        builder.append("已成功分配分红的股东:\n");
//        List<User> users = userService.getsByUserType();
        List<Integer> users = userRoleService.getsByUserRole(UserType.SHAREHOLDER);
        BigDecimal leftBonusCount = totalAccount;
        Map<String, Object> resultMap = new HashMap<>();
        for (Integer x : users) {
            BigDecimal bonusCount = giveShareholderBonus(x, totalAccount, coinTypeId, orderNo);
            builder.append("\t" + userRealInfoService.getByPrimaryKey(x).getRealName() + "\n");
            leftBonusCount = leftBonusCount.subtract(bonusCount);
        }
        resultMap.put("shareholders", builder.toString());
        resultMap.put("leftBonusCount", leftBonusCount);
        ShareholderBonusList shareholderBonusList = new ShareholderBonusList();
        Integer maxId = shareholderBonusListService.getMaxId();
        shareholderBonusList.setId((maxId + 1));
        shareholderBonusList.setTotalBonus(totalAccount);
        shareholderBonusList.setSuccessBonus(totalAccount.subtract(leftBonusCount));
        shareholderBonusList.setLeftBonus(leftBonusCount);
        shareholderBonusList.setCoinTypeId(coinTypeId);
        shareholderBonusList.setBonusKey(orderNo);
        shareholderBonusListService.insert(shareholderBonusList);
        baseDto.setData(resultMap);
        return baseDto;
    }


    public List<ShareholderCompletedInfo> castUserCompletedInfoList(List<UserCompletedInfo> userCompletedInfoList) {
        List<ShareholderCompletedInfo> shareholderCompletedInfoList = new ArrayList<>(userCompletedInfoList.size());
        userCompletedInfoList.forEach((x) -> {
            shareholderCompletedInfoList.add((ShareholderCompletedInfo) x);
        });
        return shareholderCompletedInfoList;
    }

    public void checkOverdue() {
        ShareholderShouldPay shareholderShouldPay = new ShareholderShouldPay();
        shareholderShouldPay.clearCreateTimeAndUpdateTime();
        shareholderShouldPay.setDeleted(0);
        shareholderShouldPay.setOverdue(0);
        List<ShareholderShouldPay> shareholderShouldPayList = shareholderShouldPayService.gets(shareholderShouldPay);
        for (ShareholderShouldPay shareholderShouldPay1 : shareholderShouldPayList) {
            LocalDateTime latestPayTime = shareholderShouldPay1.getLatestPayTime();
            int i = latestPayTime.compareTo(LocalDateTime.now());
            if (i != 1) {
                shareholderShouldPay1.setOverdue(1);
            }
        }
    }

    /**
     * 删除一个等级
     *
     * @return
     */
    public String deleteLevel(Integer level) {
        if (levelGrantService.delete(level))
            return "success";
        return "等级" + level + "下还有股东数据，请修改这些股东等级后再次尝试";
    }

    /**
     * 检查股东状态，判断股东状态是否正常或是否有本金支付逾期
     *
     * @param shareholderId
     * @return
     */
    protected boolean checkShareholderState(Integer shareholderId) {
        /** 获取股东状态，如果股东状态不正常，就不予发放 **/
        Integer state = userService.getByPrimaryKey(shareholderId).getState();
        if (state != UserState.OK) {
            return false;
        }

        /** 查看该股东是否有本金逾期未交，如果有，则不予发放 **/
        List<ShareholderShouldPay> shareholderShouldPayList = shareholderShouldPayService.getsByShareholderId(shareholderId);
        boolean isOverdue = false;
        for (ShareholderShouldPay shareholderShouldPay : shareholderShouldPayList) {
            if (shareholderShouldPay.getOverdue() == 1) {
                isOverdue = true;
                break;
            }
        }
        return !isOverdue;
    }

    protected ShareholderCompletedInfo castUserCapitalToShareholderCompletedInfo(UserCapital userCapital) {
        return (ShareholderCompletedInfo) super.castUserCapitalToUserCompletedInfo(userCapital);
    }


    protected ShareholderCompletedInfo castUserRealInfoToShareholderCompletedInfo(UserRealInfo userRealInfo) {
        return (ShareholderCompletedInfo) super.castUserRealInfoToUserCompletedInfo(userRealInfo);
    }


    protected ShareholderCompletedInfo castUserToShareholderCompletedInfo(User user) {
        return (ShareholderCompletedInfo) super.castUserToUserCompletedInfo(user);
    }


    protected ShareholderCompletedInfo createShareholderCompletedInfo(Integer userId) {
        UserCompletedInfo userCompletedInfo = new ShareholderCompletedInfo();
        User user = userService.getByPrimaryKey(userId);
        userCompletedInfo.setUser(user);
        userCompletedInfo.setUserBankCardList(userBankCardService.getsByUserId(userId));
        userCompletedInfo.setUserCapitalList(userCapitalService.getsByUserId(userId));
        userCompletedInfo.setUserInfo(userInfoService.getByPrimaryKey(userId));
        UserRealInfo userRealInfo = userRealInfoService.getByPrimaryKey(userId);
        if (userRealInfo == null) {
        } else {
            String idCardNum = userRealInfo.getIdCardNum();
            userRealInfo.setIdCardNum(idCardNum.substring(0, 4) + "****" + idCardNum.substring(idCardNum.length() - 4));
            userCompletedInfo.setUserRealInfo(userRealInfo);
        }
        UserInfoBind userInfoBind = userInfoBindService.getByPrimaryKey(userId);
        String smsPhoneNum = "";
        if (user.getType()== UserType.MEMBER)
            smsPhoneNum = userInfoBind.getPhoneNum();
        if (user.getType() == UserType.SHAREHOLDER)
            smsPhoneNum = userInfoBind.getSPhoneNum();
        userInfoBind.setSmsPhoneNum(smsPhoneNum);
        userCompletedInfo.setUserInfoBind(userInfoBind);
        userCompletedInfo.setUserDealHistoryList(userDealHistoryService.getByDayCount(30));
        userCompletedInfo.setTotalTransferCount(userTransferService.getTotalTransByUserId(userId));
        userCompletedInfo.setThisMonthTransferCount(userTransferService.getThisMonthCountByUserId(userId));
        /** 完善UserCompletedInfo的子类对象 **/
        complete(userCompletedInfo);
        return (ShareholderCompletedInfo) userCompletedInfo;
    }

    @Override
    protected void complete(UserCompletedInfo userCompletedInfo) {
        if (userCompletedInfo == null)
            return;
        if (!(userCompletedInfo instanceof ShareholderCompletedInfo)) {
            super.complete(userCompletedInfo);
            return;
        }
        ShareholderCompletedInfo info = (ShareholderCompletedInfo) userCompletedInfo;
        Integer shareholderId = userCompletedInfo.getUser().getId();
        User user = userService.getByPrimaryKey(shareholderId);
        //UID、股东状态、注册时间、
        info.setUser(user);
        info.setUserId(shareholderId);
        Integer state = user.getState();
        if (state == 0) {
            info.setUserStateName("正常");
        } else if (state == 1) {
            info.setUserStateName("冻结");
        } else if (state == 2) {
            info.setUserStateName("封号");
        } else if (state == 3) {
            info.setUserStateName("未激活");
        }

        info.setRegisterTime(user.getCreateTime());
        UserRealInfo userRealInfo = userRealInfoService.getByPrimaryKey(shareholderId);

        String cardNum = "";
        String cardType = "";
        String userRealName = "";
        if (userRealInfo == null) {
            //证件类型、证件号码
            info.setCardNum(cardNum);
            info.setCardType(cardType);
            info.setUserRealName(userRealName);
        } else {
            info.setCardNum(userRealInfo.getIdCardNum());
            info.setUserRealName(userRealInfo.getRealName());
            info.setCardType(cardTypeService.getByPrimaryKey(userRealInfo.getCardTypeId()).getName());
        }

        //手机号
        String phoneNum = userInfoBindService.getPhoneNumByUserId(shareholderId);
        if (!StringUtils.hasText(phoneNum)) {
            info.setPhoneNum("空");
        } else {
            info.setPhoneNum(phoneNum);
        }

        //股东等级
        ShareholderLevel shareholderLevel = shareholderLevelService.getByShareholderId(shareholderId);
        if (shareholderLevel == null) {
            info.setShareholderLevel(0);
        } else {
            info.setShareholderLevel(shareholderLevel.getLevel());
        }
        List<ShareholderBonus> shareholderBonuses = shareholderBonusService.getsByShareholderId(shareholderId);
        if (shareholderBonuses == null || shareholderBonuses.isEmpty()) {
            info.setTotalBonusCount(new BigDecimal(0));
        }
        //累计分红
        BigDecimal totalBonusCount = new BigDecimal(0);
        for (ShareholderBonus shareholderBonus : shareholderBonuses) {
            BigDecimal bonusBonus = shareholderBonus.getBonus();
            totalBonusCount = totalBonusCount.add(bonusBonus);
        }
        info.setTotalBonusCount(totalBonusCount);

        //本月分红
        BigDecimal thisMonthBonusCount = new BigDecimal(0);
        List<ShareholderBonus> thisMonthBonusByShareholderId = shareholderBonusService.getThisMonthBonusByShareholderId(shareholderId);
        if (thisMonthBonusByShareholderId.isEmpty()) {
            info.setThisMonthBonusCount(new BigDecimal(0));
        }
        for (ShareholderBonus shareholderBonus : thisMonthBonusByShareholderId) {
            BigDecimal bonusBonus = shareholderBonus.getBonus();
            thisMonthBonusCount = thisMonthBonusCount.add(bonusBonus);
        }
        info.setThisMonthBonusCount(thisMonthBonusCount);
        //转股东活币
//         = userTransferService.getTransferByUserType(shareholderId,UserType.SHAREHOLDER);
        BigDecimal transferToShareholder = new BigDecimal(0);
        List<TransferHistoryDto> userTransferToShareholder = userDealHistoryService.getUserTransferToShareholder(shareholderId);
        if (userTransferToShareholder != null && !userTransferToShareholder.isEmpty()) {
            for (TransferHistoryDto transferHistoryDto : userTransferToShareholder) {
                BigDecimal transferCount = transferHistoryDto.getTransferCount();
                transferToShareholder = transferToShareholder.add(transferCount);
            }
        }
        info.setTransferToShareholder(transferToShareholder);
        List<UserCapital> userCapitalList = userCapitalService.getsByUserId(shareholderId);
        if (userCapitalList == null || userCapitalList.isEmpty()) {
            info.setSleepCount(new BigDecimal(0));
            info.setSleepCount(new BigDecimal(0));
        }
        //休眠币数量
        BigDecimal sleepCount = new BigDecimal(0);
        for (UserCapital userCapital : userCapitalList) {
            BigDecimal sleepCoinCount = userCapital.getSleepCoinCount();
            sleepCount = sleepCount.add(sleepCoinCount);
        }
        info.setSleepCount(sleepCount);
        //活币持有量
        BigDecimal aliveCount = new BigDecimal(0);
        for (UserCapital userCapital : userCapitalList) {
            BigDecimal aliveCoinCount = userCapital.getAliveCoinCount();
            aliveCount = aliveCount.add(aliveCoinCount);
        }
        info.setAliveCount(aliveCount);

        //活币配发量
        BigDecimal aliveGrantCount = new BigDecimal(0);
        List<AliveCoinActivateHistory> aliveHistory = aliveCoinActivateHistoryService.getByShareholderId(shareholderId);
        if (aliveHistory == null || aliveHistory.isEmpty()) {
            info.setAliveGrantCount(new BigDecimal(0));
        }
        for (AliveCoinActivateHistory aliveCoinActivateHistory : aliveHistory) {
            aliveGrantCount = aliveGrantCount.add(aliveCoinActivateHistory.getCount());
        }
        info.setAliveGrantCount(aliveGrantCount);
    }

    public BaseDto search(int pageNum,
                          int pageSize,
                          String realName,
                          String phoneNum,
                          String idCardNum,
                          int coinTypeId,
                          Integer lowLevel,
                          Integer highLevel,
                          LocalDateTime lowRegistryDate,
                          LocalDateTime highRegistryDate,
                          BigDecimal lowSleepCoinCount,
                          BigDecimal highSleepCoinCount,
                          BigDecimal lowAliveCoinCount,
                          BigDecimal highAliveCoinCount,
                          Integer shareholderState) {
        List<ShareholderCompletedInfo> shareholderCompletedInfoList = new ArrayList<>();
        List<Integer> ids = new ArrayList<>();
        List<Integer> shareholderIds = userRoleService.getsByUserRole(UserType.MEMBER);
        Map<String, Object> userRealInfoParamMap = new HashMap<>();
        if (StringUtils.hasText(realName)) {
            userRealInfoParamMap.put("realName", realName);
        }
        if (StringUtils.hasText(phoneNum)) {
            userRealInfoParamMap.put("phoneNum", phoneNum);
        }
        if (StringUtils.hasText(idCardNum)) {
            userRealInfoParamMap.put("idCardNum", idCardNum);
        }
        List<UserRealInfo> userRealInfoList = userRealInfoService.getsWithoutComplete(userRealInfoParamMap);
        if (userRealInfoList != null && !userRealInfoList.isEmpty()) {
            userRealInfoList.forEach((x) -> {
                ids.add(x.getId());
            });
            shareholderIds.retainAll(ids);
            ids.clear();
        }

        if (lowLevel != null && highLevel != null) {
            List<ShareholderLevel> shareholderLevelList = shareholderLevelService.searchByLevel(lowLevel, highLevel);
            shareholderLevelList.forEach((x) -> {
                ids.add(x.getShareholderId());
            });
            shareholderIds.retainAll(ids);
            ids.clear();
        }

        if (lowRegistryDate != null && highRegistryDate != null) {
            List<User> userList = userService.searchByRegistDate(lowRegistryDate, highRegistryDate);
            userList.forEach((x) -> {
                ids.add(x.getId());
            });
            shareholderIds.retainAll(ids);
            ids.clear();
        }

        CommonExample example = new CommonExample(UserCapital.class);
        boolean flag = false;
        example.equals("coinTypeId", coinTypeId);
        if (lowSleepCoinCount != null && highSleepCoinCount != null) {
            example.between("sleepCoinCount", lowSleepCoinCount, highSleepCoinCount);
            flag = true;
        }
        if (lowAliveCoinCount != null && highAliveCoinCount != null) {
            example.between("aliveCoinCount", lowAliveCoinCount, highAliveCoinCount);
            flag = true;
        }

        if (flag) {
            List<UserCapital> userCapitalList = userCapitalService.getsByExampleWithoutComplete(example);
            userCapitalList.forEach((x) -> {
                ids.add(x.getUserId());
            });
            shareholderIds.retainAll(ids);
            ids.clear();
        }

        if (shareholderState != null) {
            CommonExample example1 = new CommonExample(User.class);
            example1.equals("type", UserType.SHAREHOLDER);
            example.equals("state", shareholderState);
            List<User> userList = userService.getsByExampleWithoutComplete(example);
            userList.forEach((x) -> {
                ids.add(x.getId());
            });
            shareholderIds.retainAll(ids);
            ids.clear();
        }

        for (Integer shareholderId : shareholderIds) {
            ShareholderCompletedInfo shareholderCompletedInfo = this.searchByUserId(shareholderId);
            shareholderCompletedInfoList.add(shareholderCompletedInfo);
        }
        BaseDto baseDto = new BaseDto();
        Page page = PageHelper.startPage(pageNum, pageSize);
        baseDto.setData(new PageInfo<ShareholderCompletedInfo>(shareholderCompletedInfoList));
        return baseDto;

    }

    @Override
    public ShareholderCompletedInfo searchByUserId(Integer userId) {
        return createShareholderCompletedInfo(userId);
    }

    public BigDecimal getTotalDivdends() {
        List<ShareholderBonus> all = shareholderBonusService.getAll();
        BigDecimal totalCount = new BigDecimal(0);
        if (all == null || all.isEmpty()) {
            return totalCount;
        }
        for (ShareholderBonus shareholderBonus : all) {
            BigDecimal bonus = shareholderBonus.getBonus();
            totalCount = totalCount.add(bonus);
        }
        return totalCount;
    }

    public List<ShareholderBonus> getDividensHistory() {
        List<ShareholderBonus> all = shareholderBonusService.getAll();
        ArrayList<ShareholderBonus> shareholderBonuses = new ArrayList<>();
        for (ShareholderBonus shareholderBonus : all) {
            Integer shareholderId = shareholderBonus.getShareholderId();
            shareholderBonus.setUserState(userService.getByPrimaryKey(shareholderId).getState());
            shareholderBonuses.add(shareholderBonus);
        }
        return shareholderBonuses;
    }

    public List<ShareholderCoinGrantHistory> getDistributeHistory() {
        List<ShareholderCoinGrantHistory> all = shareholderCoinGrantHistoryService.getAll();
        return all;
    }

    public BigDecimal getMonthDivdends() {
        BigDecimal monthDivdends = shareholderBonusService.getThisMonthBonus();
        return monthDivdends;
    }

    public BigDecimal getTotalDistribute() {
        List<AliveCoinActivateHistory> all = aliveCoinActivateHistoryService.getAllWithoutComplete();
        BigDecimal totalDistribute = new BigDecimal(0);
        if (all != null) {
            for (AliveCoinActivateHistory aliveCoinActivateHistory : all) {
                BigDecimal aliveCoinCount = aliveCoinActivateHistory.getCount();
                totalDistribute = totalDistribute.add(aliveCoinCount);
            }
        }

        return totalDistribute;
    }

    protected BigDecimal getMonthDistributeByUserId(Integer userId) {

        TimeExample example = new TimeExample(AliveCoinActivateHistory.class);
        example.equals("shareholderId", userId);
        Example.Criteria criteria = example.getCriteria();
        criteria.andGreaterThanOrEqualTo("createTime", LocalDateTimeUtil.getThisMonthFirstDay());
        List<AliveCoinActivateHistory> aliveCoinActivateHistories = aliveCoinActivateHistoryService.getsByExampleWithoutComplete(example);
        BigDecimal monthTransfer = new BigDecimal(0);
        if (aliveCoinActivateHistories != null) {
            for (AliveCoinActivateHistory aliveCoinActivate : aliveCoinActivateHistories) {
                monthTransfer = monthTransfer.add(aliveCoinActivate.getCount());
            }
        }
        return monthTransfer;
    }

    public BigDecimal getMonthDistribute() {
        List<Integer> userList = userRoleService.getsByUserRole(UserType.SHAREHOLDER);
        BigDecimal monthDistribute = new BigDecimal(0);
        if (userList != null) {
            for (Integer integer : userList) {
                BigDecimal monthDistributeByUserId = getMonthDistributeByUserId(integer);
                monthDistribute = monthDistribute.add(monthDistributeByUserId);
            }
        }
//        for (User user : userList) {
//            BigDecimal monthDistributeByUserId = getMonthDistributeByUserId(user.getId());
//            monthDistribute = monthDistribute.add(monthDistributeByUserId);
//        }
        return monthDistribute;
    }

    /**
     * 根据phoneNum和IdCardNum查询股东未分红记录
     *
     * @param phoneNum
     * @param IdCardNum
     * @return
     */
    public List<ShareholderBonus> getDisDividendsListByPhoneNumAndIdCard(String phoneNum, String IdCardNum) {
        Integer userId = userRealInfoService.getUserIdByPhoneNumAndIdCard(phoneNum, IdCardNum);
        List<ShareholderBonus> all = shareholderBonusService.getsDisByShareholderId(userId);
        ArrayList<ShareholderBonus> shareholderBonuses = new ArrayList<>();
        if (all != null) {
            for (ShareholderBonus shareholderBonus : all) {
                Integer shareholderId = shareholderBonus.getShareholderId();
                shareholderBonus.setUserState(userService.getByPrimaryKey(shareholderId).getState());
                shareholderBonuses.add(shareholderBonus);
            }
        }
        return shareholderBonuses;
    }

    public Map updateDividends(Integer bonusId, Integer userId) {
        ShareholderBonus shareholderBonus = shareholderBonusService.getByPrimaryKey(bonusId);
        ShareholderBonusList shareholderBonusList = shareholderBonusListService.getByKey(shareholderBonus.getBonusKey());
        boolean flag = checkShareholderState(userId);
        if (flag) {
            BigDecimal bonusUnPay = shareholderBonus.getBonusUnpay();
            shareholderBonus.setBonus(bonusUnPay);
            shareholderBonus.setBonusUnpay(new BigDecimal(0));
            shareholderBonusService.update(shareholderBonus);//修改 bonus和bonusUnPay
            cashWalletService.addCash(userId, bonusUnPay, CashChangeType.CASH_SHAREHOLDER_BONES, shareholderBonus.getBonusKey());//转账
            BigDecimal totalBonus = shareholderBonusList.getTotalBonus();
            BigDecimal successBonus = shareholderBonusList.getSuccessBonus();
            BigDecimal leftBonus = shareholderBonusList.getLeftBonus();

            shareholderBonusList.setSuccessBonus(successBonus.add(bonusUnPay));
            shareholderBonusList.setLeftBonus(leftBonus.subtract(bonusUnPay));
            shareholderBonusListService.update(shareholderBonusList);//修改bonusList
        }
        UserRealInfo userRealInfo = userRealInfoService.getByPrimaryKey(userId);
        String idCardNum = userRealInfo.getIdCardNum();
        Map map = new HashMap();
        String phoneNum = userInfoBindService.getByPrimaryKey(userId).getSPhoneNum();
        map.put("idCardNum", idCardNum);
        map.put("phoneNum", phoneNum);
        map.put("flag", flag);
        return map;
    }

    public ShareholderCompletedInfo getByUserId(Integer userId) {
        ShareholderCompletedInfo info = new ShareholderCompletedInfo();
        User user = userService.getByPrimaryKey(userId);
        //UID、股东状态、注册时间、
        info.setUser(user);
        info.setUserId(userId);
        info.setUserState(user.getState());
        info.setRegisterTime(user.getCreateTime());
        UserRealInfo userRealInfo = userRealInfoService.getByPrimaryKey(userId);
        if (userRealInfo.getRealName() == null) {
            info.setCardNum("空");
            info.setCardType("空");
            info.setUserRealName("空");
        }

        info.setUserRealInfo(userRealInfo);
        //证件类型、证件号码
        info.setCardNum(userRealInfo.getIdCardNum());
        info.setCardType(cardTypeService.getByPrimaryKey(userRealInfo.getCardTypeId()).getName());
        //姓名、手机号
        info.setUserRealName(userRealInfo.getRealName());
        String phoneNum = userInfoBindService.getPhoneNumByUserId(userId);
        if (phoneNum.length() == 0 || StringUtils.hasText(phoneNum)) {
            info.setPhoneNum("空");
        }
        info.setPhoneNum(phoneNum);

        //股东等级
        ShareholderLevel shareholderLevel = shareholderLevelService.getByShareholderId(userId);
        info.setShareholderLevel(shareholderLevel.getLevel());
        List<ShareholderBonus> shareholderBonuses = shareholderBonusService.getsByShareholderId(userId);
        if (shareholderBonuses == null || shareholderBonuses.isEmpty()) {
            info.setTotalBonusCount(new BigDecimal(0));
            info.setThisMonthBonusCount(new BigDecimal(0));
        }

        //累计分红
        BigDecimal totalBonusCount = new BigDecimal(0);
        for (ShareholderBonus shareholderBonus : shareholderBonuses) {
            BigDecimal bonusBonus = shareholderBonus.getBonus();
            totalBonusCount = totalBonusCount.add(bonusBonus);
        }
        info.setTotalBonusCount(totalBonusCount);
        //本月分红
        BigDecimal thisMonthBonusCount = new BigDecimal(0);
        List<ShareholderBonus> thisMonthBonusByShareholderId = shareholderBonusService.getThisMonthBonusByShareholderId(userId);
        for (ShareholderBonus shareholderBonus : thisMonthBonusByShareholderId) {
            BigDecimal bonusBonus = shareholderBonus.getBonus();
            thisMonthBonusCount = thisMonthBonusCount.add(bonusBonus);
        }
        info.setThisMonthBonusCount(thisMonthBonusCount);
        //转股东活币
        info.setTransferToShareholder(userTransferService.getTransferByUserType(userId, UserType.SHAREHOLDER));
        List<UserCapital> userCapitalList = userCapitalService.getsByUserId(userId);
        if (userCapitalList == null || userCapitalList.isEmpty()) {
            info.setSleepCount(new BigDecimal(0));
            info.setSleepCount(new BigDecimal(0));
        }

        //休眠币数量
        BigDecimal sleepCount = new BigDecimal(0);
        for (UserCapital userCapital : userCapitalList) {
            BigDecimal sleepCoinCount = userCapital.getSleepCoinCount();
            sleepCount = sleepCount.add(sleepCoinCount);
        }

        info.setSleepCount(sleepCount);
        //活币持有量
        BigDecimal aliveCount = new BigDecimal(0);
        for (UserCapital userCapital : userCapitalList) {
            BigDecimal aliveCoinCount = userCapital.getAliveCoinCount();
            aliveCount = aliveCount.add(aliveCoinCount);
        }
        info.setSleepCount(aliveCount);

        //活币配发量
        BigDecimal aliveGrantCount = new BigDecimal(0);
        List<AliveCoinActivateHistory> aliveHistory = aliveCoinActivateHistoryService.getByShareholderId(userId);
        if (aliveHistory == null || aliveHistory.isEmpty()) {
            info.setAliveGrantCount(new BigDecimal(0));
        }
        for (AliveCoinActivateHistory aliveCoinActivateHistory : aliveHistory) {
            aliveGrantCount = aliveGrantCount.add(aliveCoinActivateHistory.getCount());
        }
        info.setAliveGrantCount(aliveGrantCount);
        complete(info);
        return info;
    }


    public List<ShareholderCompletedInfo> searchSByNameAndPhoneNumAndIdCardNum(String userName, String phoneNum, String idCardNum) {
        ArrayList<ShareholderCompletedInfo> list = new ArrayList<>();
        Integer userIdByPhoneNum = getUserIdByPhoneNum(phoneNum);
        Integer userIdByIdCardNum = getUserIdByIdCardNum(idCardNum);
        List<Integer> userIdByUserName = getUserIdByUserName(userName);

        if (!userRoleService.hasRole(userIdByPhoneNum, UserType.SHAREHOLDER)) {
        } else if (userIdByPhoneNum != null) {
            list.add(searchByUserId(userIdByPhoneNum));
        }

        if (!userRoleService.hasRole(userIdByIdCardNum, UserType.SHAREHOLDER)) {
        } else if (userIdByIdCardNum != null) {
            list.add(searchByUserId(userIdByIdCardNum));
        }

        if (userIdByUserName == null || userIdByUserName.isEmpty()) {
        } else {
            for (Integer integer : userIdByUserName) {
                if (!userRoleService.hasRole(integer, UserType.SHAREHOLDER)) {
                } else if (integer != null) {
                    list.add(searchByUserId(integer));
                }
            }
        }

        return list;
    }

    public ShareholderDetail shareholderUserDetail(Integer userId,
                                                   Integer coinTypeId,
                                                   Integer userType) {
        ShareholderDetail shareholderDetail = new ShareholderDetail();
        UserRealInfo userRealInfo = userRealInfoService.getByPrimaryKey(userId);
        UserCapital userCapital = userCapitalService.getByUserIdAndCoinTypeIdAndUserType(userId, coinTypeId, userType);
        CoinType coinType = coinTypeService.getByPrimaryKey(coinTypeId);
        UserInfoBind userInfoBind = userInfoBindService.getByPrimaryKey(userId);
        BigDecimal aliveCoinCount = new BigDecimal(0);
        BigDecimal sleepCoinCount = new BigDecimal(0);
        if (userCapital != null) {
            aliveCoinCount = userCapital.getAliveCoinCount();
            sleepCoinCount = userCapital.getSleepCoinCount();
        }
        shareholderDetail.setAliveCoinCount(aliveCoinCount);
        shareholderDetail.setSleepCoinCount(sleepCoinCount);
        shareholderDetail.setUserId(userId);
        shareholderDetail.setUserRealName(userRealInfo.getRealName());
        shareholderDetail.setCoinTypeId(coinTypeId);
        shareholderDetail.setCoinTypeName(coinType.getName());
        shareholderDetail.setCardTypeName(userRealInfo.getCardTypeName());
        shareholderDetail.setIdCardNum(userRealInfo.getIdCardNum());
        shareholderDetail.setPhoneNum(userInfoBind.getSPhoneNum());
        if (UserType.SHAREHOLDER == userType) {
            ShareholderLevel shareholderLevel = shareholderLevelService.getByShareholderId(userId);
            shareholderDetail.setShareholderLevel(shareholderLevel.getLevel());
        }
        return shareholderDetail;
    }

}
